package com.li.utilstest

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.hardware.display.DisplayManager
import android.hardware.display.VirtualDisplay
import android.media.*
import android.media.MediaCodec.BufferInfo
import android.media.projection.MediaProjectionManager
import android.os.Binder
import android.os.Build
import android.os.IBinder
import android.util.Log
import android.view.Surface
import androidx.annotation.Nullable
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.nio.ByteBuffer


/**
 * @author : liyun
 * @ClassName: MediaRecordServer
 * @Package com.li.utilstest
 * @Description:
 * @company: 深圳君南信息系统有限公司
 * @date 2021/8/21 16:44
 * @version v1.0
 */
class MediaRecordServer: Service() {
    private var mediaRecorder: MediaRecorder? = null
    private var recordFile: File? = null
    private var width = 0
    private var height = 0
    private var surface: Surface? = null
    var virtualDisplay: VirtualDisplay? = null
    private var videoEncoder: MediaCodec? = null
    private var inputSurface: Surface? = null
    private var mediaMuxer: MediaMuxer? = null
    private var videoTrackIndex = 0
    private var bufferInfo: BufferInfo? = null
    private var isRecord = false
    private var notificationManager: NotificationManager? = null

    @Nullable
    override fun onBind(intent: Intent?): IBinder? {
        return MyBinder()
    }

    inner class MyBinder : Binder() {
        @RequiresApi(Build.VERSION_CODES.KITKAT_WATCH)
        fun paused() {
            // 置为null时,表示暂停
            virtualDisplay?.surface = null
        }

        @RequiresApi(Build.VERSION_CODES.KITKAT_WATCH)
        fun stop() {
            isRecord = false
            virtualDisplay?.surface = null
            virtualDisplay?.release()
            videoEncoder?.stop()
            videoEncoder?.release()
//            mediaMuxer?.stop()
//            mediaMuxer?.release()
            mediaRecorder?.setOnErrorListener(null)
            mediaRecorder?.setPreviewDisplay(null)
            mediaRecorder?.stop()

            notificationManager?.cancel(123123)
        }

        @RequiresApi(Build.VERSION_CODES.KITKAT_WATCH)
        fun resume() {
            virtualDisplay?.surface = surface
        }
    }

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        notificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val notification = NotificationCompat.Builder(this, "123123")
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle("录屏")
            .setContentText(resources.getString(R.string.app_name) + "录屏中")
            .build()
        if (Build.VERSION.SDK_INT >= 26) {
            // 推送通道
            val channel =
                NotificationChannel("123123", "通道说明", NotificationManager.IMPORTANCE_DEFAULT)
            notificationManager!!.createNotificationChannel(channel)
        }
        // 展示前台服务
        startForeground(123123, notification)
        val resultCode = intent.getIntExtra("resultCode", -1)
        width = intent.getIntExtra("width", -1)
        height = intent.getIntExtra("height", -1)
        val data = intent.getParcelableExtra<Intent>("data")
        surface = intent.getParcelableExtra("surface")
        val mediaProjectionManager =
            getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        val mediaProjection = mediaProjectionManager.getMediaProjection(
            resultCode,
            data!!
        )
        if (mediaProjection != null) {
            // 获取存储的位置
            recordFile = getExternalFilesDir("RecordFile")
            val mkdirs = recordFile!!.mkdirs()

            initMediaRecorder()
//            initMediaCodec()
            /*val absolutePath = File(recordFile.toString() + "/record.mp4").absolutePath
            try {
                val fos = FileOutputStream(absolutePath)
                mediaMuxer = MediaMuxer(absolutePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
                *//**
                 * 创建投影
                 * name 本次虚拟显示的名称
                 * width 录制后视频的宽
                 * height 录制后视频的高
                 * dpi 显示屏像素
                 * flags VIRTUAL_DISPLAY_FLAG_PUBLIC 通用显示屏
                 * Surface 输出位置
                 *//*
                virtualDisplay = mediaProjection.createVirtualDisplay(
                    "record-video", width, height, 6000000,
                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC, inputSurface, null, null
                )
                isRecord = true
                bufferInfo = BufferInfo()
//                readEncoderData()
            } catch (e: IOException) {
                e.printStackTrace()
            }*/

            mediaRecorder?.start()
        }
        return super.onStartCommand(intent, flags, startId)
    }

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    private fun readEncoderData() {
        Thread {
            while (isRecord) {
                // 获取已经解码的缓冲区索引
                val index = videoEncoder!!.dequeueOutputBuffer(bufferInfo!!, 10000)
                when {
                    index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED -> {
                        // 输出格式已改变
                        resetOutputFormat()
                    }
                    index == MediaCodec.INFO_TRY_AGAIN_LATER -> {
                        // 超时
                    }
                    index >= 0 -> {
                        // 获取数据
                        var outputBuffer: ByteBuffer? = videoEncoder!!.getOutputBuffer(index)
                        if (bufferInfo!!.flags and MediaCodec.BUFFER_FLAG_CODEC_CONFIG != 0) {
                            bufferInfo!!.size = 0
                        }
                        if (bufferInfo!!.size == 0) {
                            outputBuffer = null
                        } else {
                            if (outputBuffer != null) {
                                // 将 ByteBuffer 转换为 byte[]
                                    var bytes = bytebuffer2ByteArray(outputBuffer)
                                mediaMuxer!!.writeSampleData(
                                    videoTrackIndex,
                                    outputBuffer,
                                    bufferInfo!!
                                )
                            }
                        }
                        videoEncoder!!.releaseOutputBuffer(index, false)
                    }
                }
            }
        }.start()
    }

    /**
     * byteBuffer 转 byte数组
     * @param buffer
     * @return
     */
    fun bytebuffer2ByteArray(buffer: ByteBuffer): ByteArray? {
        //获取buffer中有效大小
        val len: Int = buffer.limit() - buffer.position()
        val bytes = ByteArray(len)
        buffer.get(bytes)
        return bytes
    }

    private fun initMediaCodec() {
        val MIME_TYPE = "video/avc" // H.264 类型
        val format = MediaFormat.createVideoFormat(MIME_TYPE, width, height)

        // 颜色格式
        format.setInteger(
            MediaFormat.KEY_COLOR_FORMAT,
            MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface
        )
        // 比特率
        format.setInteger(MediaFormat.KEY_BIT_RATE, 6000000)
        // 帧速率
        format.setInteger(MediaFormat.KEY_FRAME_RATE, 60)
        // I帧的帧率
        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10)
        try {
            // 创建指定类型的编码器
            videoEncoder = MediaCodec.createEncoderByType(MIME_TYPE)
            // 设置编码器属性
            videoEncoder!!.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
            // 创建作为输入的 Surface
            inputSurface = videoEncoder!!.createInputSurface()
            videoEncoder!!.start()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    private fun resetOutputFormat() {
        val newFormat = videoEncoder!!.outputFormat
        videoTrackIndex = mediaMuxer!!.addTrack(newFormat)
        mediaMuxer!!.start()
    }

    private fun initMediaRecorder() {
        mediaRecorder = MediaRecorder()
        // 设置音频来源
        mediaRecorder!!.setAudioSource(MediaRecorder.AudioSource.MIC)
        // 设置视频来源
        mediaRecorder!!.setVideoSource(MediaRecorder.VideoSource.SURFACE)
        // 设置输出格式
        mediaRecorder!!.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
        // 设置输出文件
        val absolutePath = File(recordFile.toString() + "/record.mp4").absolutePath
        Log.e("PATH", absolutePath)
        mediaRecorder!!.setOutputFile(absolutePath)
        // 设置视频宽高
        mediaRecorder!!.setVideoSize(width, height)
        // 设置视频帧率
        mediaRecorder!!.setVideoFrameRate(60)
        // 设置视频编码比特率
        mediaRecorder!!.setVideoEncodingBitRate(6000000)
        // 设置音频编码
        mediaRecorder!!.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
        // 设置视频编码
        mediaRecorder!!.setVideoEncoder(MediaRecorder.VideoEncoder.H264)
        try {
            mediaRecorder!!.prepare()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
}